﻿Imports Microsoft.VisualBasic

Imports System.Collections
Imports System.Data
Imports System.Web.SessionState
Imports System.Text

Imports ZetaCompressionLibrary ' Thu vien nen chuoi du lieu. Ap dung vao Url

Public Class EncriptUrl
    Public Shared Function EncodeQueryString(ByVal strOrgQuery As String) As String
        Try
            If strOrgQuery.Length > 0 Then
                Dim arrBytes As Byte()

                arrBytes = CompressionHelper.CompressString(strOrgQuery)
                Dim encStr As String = Convert.ToBase64String(arrBytes)
                'encStr = encStr.Replace("=", "*")
                'encStr = encStr.Replace("+", "-")
                'encStr = encStr.Replace("/", "_")
                Return encStr
            Else
                Return strOrgQuery
            End If
        Catch
            Return strOrgQuery
        End Try
    End Function

    Public Shared Function DecodeQueryString(ByVal strEncQuery As String) As String
        Try
            If strEncQuery.Length > 0 Then
                Dim arrBytes As Byte()
                'strEncQuery = strEncQuery.Replace("*", "=")
                'strEncQuery = strEncQuery.Replace("-", "+")
                'strEncQuery = strEncQuery.Replace("_", "/")
                arrBytes = Convert.FromBase64String(strEncQuery)
                Return CompressionHelper.DecompressString(arrBytes)
            Else
                Return strEncQuery
            End If
        Catch generatedExceptionName As Exception
            Return strEncQuery
        End Try
    End Function

End Class

Public Class FormStatus
    Public mParaList As New RowData()

    Public Property PageName() As String
        Get
            Return DirectCast(mParaList("Page"), String)
        End Get
        Set(ByVal value As String)
            mParaList("Page") = value
        End Set
    End Property

    Public ReadOnly Property ParentPageName() As String
        Get
            Dim fs As New FormStatus(EncriptUrl.DecodeQueryString(ParentParameter))
            Return fs.PageName
        End Get
    End Property

    Public Property ParentParameter() As String
        Get
            Return DirectCast(mParaList("PARENTPAR"), String)
        End Get
        Set(ByVal value As String)
            mParaList("PARENTPAR") = value
        End Set
    End Property

    Public ReadOnly Property ParentFormStatus() As FormStatus
        Get
            Return New FormStatus(EncriptUrl.DecodeQueryString(ParentParameter))
        End Get
    End Property


    Default Public Property Item(ByVal index As String) As String
        Get
            Dim strReturn As String

            strReturn = DirectCast(mParaList(index), String)

            If strReturn IsNot Nothing Then
                Return strReturn.Replace("-cvam-", "&")
            End If
            Return strReturn
        End Get
        Set(ByVal value As String)
            Dim strValue As String

            strValue = Convert.ToString(value)
            If strValue IsNot Nothing Then
                mParaList(index) = strValue.Replace("&", "-cvam-")
            Else
                mParaList(index) = strValue
            End If
        End Set
    End Property


    Default Public Property Item(ByVal index As Integer) As String
        Get
            Return DirectCast(mParaList(index), String)
        End Get
        Set(ByVal value As String)
            mParaList(index) = value
        End Set
    End Property


    Public Sub New()
    End Sub

    Public Sub New(ByVal fs As FormStatus)
        mParaList = New RowData(fs.mParaList)
    End Sub

    Public Sub New(ByVal decodeStr As String)
        ParseStringToValue(decodeStr)
    End Sub

    Public Function HasInfor() As Boolean
        Return (mParaList.ParameterArray.Count > 0)
    End Function

    Public Sub Clear()
        mParaList.Clear()
    End Sub

    Public Sub ParseStringToValue(ByVal decodeStr As String)
        Try
            Dim strQueries As String() = decodeStr.Split(New Char() {"&"c})
            For i As Integer = 0 To strQueries.Length - 1
                If strQueries(i).Length > 1 Then
                    Dim strParams As String() = strQueries(i).Split(New Char() {"="c})
                    mParaList(strParams(0)) = strParams(1)
                End If
            Next
        Catch generatedExceptionName As Exception
        End Try
    End Sub

    Public Overrides Function ToString() As String
        Dim str As String = ""
        For i As Integer = 0 To mParaList.ParameterArray.Count - 1
            str += mParaList.GetIndexName(i) & "=" & DirectCast(mParaList(i), String) & "&"
        Next
        str = (str & "&").Replace("&&", "")
        Return str
    End Function
End Class


''' <summary>
''' Using this class:
''' we have  chain like this : Form1 .--. Form2 .--. Form3 .--. Form4 .--. Form5
''' 1.forward : Form1 --. form2 : Parametter from Form 1 has no parent parametter
''' 2.Bacward : Form1 .-- Form2 (Form2 did Not go to form 3): Parametter from Form 2 has parent parametter 
''' 3.forward : Form2 --. Form3: Parametter from Form2  has parent parametter
''' 4.Bacward : Form1 .-- Form2 : Parametter from Form3  has parent parametter of Form2 and Form1 ...
''' All Parameter you want to send from Form to Form  : Add to mCurrentFormStatus
''' 1. If you want to go back from form 3 to form2 just use ToString(PageNavigator.BACK)
''' 2. If you want to go from form 2 to form3 just use ToString(PageNavigator.Next)
''' 3. If you want to refer to Parent form paramter use :mParentFormStatus.ParentFormStatus
''' 4. If you want to refer to Parent of Parent form paramter use :mParentFormStatus.ParentFormStatus.ParentFormStatus ... and so on
''' So easy
''' Note that do not add to much parameter to the class, max len is 2090.
''' </summary>
''' 

Public Class PageParameter

    Public mParentFormStatus As FormStatus = Nothing
    Public mCurrentFormStatus As FormStatus = Nothing
    Private mstrDecodePar As String = ""

    Public Sub New()
        mParentFormStatus = New FormStatus()
        mCurrentFormStatus = New FormStatus()
    End Sub

    Public Sub New(ByVal encodeStr As String)
        If encodeStr Is Nothing OrElse encodeStr.Length < 1 Then
            mParentFormStatus = New FormStatus()
            mCurrentFormStatus = New FormStatus()
            Return
        End If

        mstrDecodePar = EncriptUrl.DecodeQueryString(encodeStr)

        If mstrDecodePar.Length > 0 Then
            mCurrentFormStatus = New FormStatus(mstrDecodePar)
        Else
            mCurrentFormStatus = New FormStatus()
        End If

        mParentFormStatus = New FormStatus(mCurrentFormStatus)
    End Sub

    Public Overloads Function ToString(ByVal pn As PageNavigator) As String
        Dim str As String = ""
        If pn = PageNavigator.[NEXT] Then
            If mCurrentFormStatus IsNot Nothing Then
                If mParentFormStatus IsNot Nothing AndAlso mParentFormStatus.HasInfor() Then
                    mCurrentFormStatus.ParentParameter = EncriptUrl.EncodeQueryString(mParentFormStatus.ToString())
                ElseIf mCurrentFormStatus.ParentParameter Is Nothing Then
                    ' IF PAREANT FORM STATUS EMPTY THAT MEAN THIS FORM IS FIRST FORM IN THE CHAIN, THEN PARENTPAR= CURRENT PAR
                    mCurrentFormStatus.ParentParameter = EncriptUrl.EncodeQueryString(mCurrentFormStatus.ToString())
                End If

                str = mCurrentFormStatus.ToString() & "&"
            End If
        Else
            ' PageNavigator.PRIVOUS
            If mParentFormStatus IsNot Nothing AndAlso mParentFormStatus.ParentParameter IsNot Nothing Then
                str = EncriptUrl.DecodeQueryString(mParentFormStatus.ParentParameter) & "&"
            End If
            If mCurrentFormStatus IsNot Nothing Then
                str += mCurrentFormStatus.ToString() & "&"

            End If
        End If
        Return str
    End Function

End Class

Public Class RowData
    ''' <summary>
    ''' Use this class to store the row data that you get from DB, or any,
    ''' each record(row) have more than 1 item and can get/set via the name of item
    ''' can refer to Item.cs for detail ex.
    ''' </summary>

    Private m_ParArr As ArrayList
    Private m_StringIndexer As ArrayList

    Public ReadOnly Property ParameterArray() As ArrayList
        Get
            Return m_ParArr
        End Get
    End Property

    Default Public Property Item(ByVal index As Integer) As Object
        Get
            ' Check the index limits.
            If index >= 0 OrElse index <= m_ParArr.Count Then
                Return m_ParArr(index)
            Else
                Return Nothing
            End If
        End Get
        Set(ByVal value As Object)
            If Not (index < 0 OrElse index >= m_ParArr.Count) Then
                m_ParArr(index) = value
            Else
                Throw (New IndexOutOfRangeException())
            End If
        End Set
    End Property


    Default Public Property Item(ByVal index As String) As Object
        Get
            Dim i As Integer = 0
            While i < m_StringIndexer.Count
                If index.ToLower() = m_StringIndexer(i).ToString().ToLower() Then
                    Exit While
                End If
                i += 1
            End While
            If i < m_StringIndexer.Count Then
                Return Me(i)
            Else
                Return Nothing

            End If
        End Get
        Set(ByVal value As Object)
            If (value Is Nothing) OrElse (value.ToString().Length < 1) Then
                Return
            End If
            Dim i As Integer = 0
            While i < m_StringIndexer.Count
                If index.ToLower() = m_StringIndexer(i).ToString().ToLower() Then
                    Exit While
                End If
                i += 1
            End While
            If i < m_StringIndexer.Count Then
                Me(i) = value
            Else
                Me.Add(index, value)
            End If
        End Set
    End Property


    Public Sub New()
        m_ParArr = New ArrayList()
        m_StringIndexer = New ArrayList()
    End Sub

    Public Sub New(ByVal rd As RowData)
        m_ParArr = New ArrayList()
        m_StringIndexer = New ArrayList()
        For i As Integer = 0 To rd.m_ParArr.Count - 1
            m_ParArr.Add(rd.m_ParArr(i))
            m_StringIndexer.Add(rd.m_StringIndexer(i))
        Next
    End Sub

    Public Sub New(ByVal aList As ArrayList)
        m_ParArr = aList
    End Sub

    Public Function GetIndexName(ByVal index As Integer) As String
        If index >= 0 OrElse index <= m_ParArr.Count Then
            Return DirectCast(m_StringIndexer(index), String)
        Else
            Return Nothing
        End If
    End Function

    Public Overrides Function ToString() As String
        Return DirectCast(m_ParArr(0), String)
    End Function

    Public Sub Add(ByVal sIndex As String, ByVal oValue As Object)
        m_ParArr.Add(oValue)
        m_StringIndexer.Add(sIndex)
    End Sub

    Public Sub Clear()
        If m_ParArr IsNot Nothing Then
            m_ParArr.Clear()
        End If
        If m_StringIndexer IsNot Nothing Then
            m_StringIndexer.Clear()
        End If
    End Sub
End Class